import cv2
import numpy as np
import os


def show_img(img, title="title"):
    cv2.imshow(title, img)
    # 关闭窗口
    cv2.waitKey()
    cv2.destroyAllWindows()


# img_a = 'temp/a1.jpg'
img_a = 'temp/a4.jpg'
# img_a = 'temp/b2.jpg'
# img_a = 'temp/b1.jpg'
# img_a = 'temp/b5.jpg'


# 读取名称为 p9.png的图片
# org = cv2.imread(img_a, 1)
img = cv2.imread(img_a, 1)
img = cv2.resize(img, (720, 480))
# show_img(img, 'img')


# 模糊处理
# blur = cv2.pyrMeanShiftFiltering(img, 25, 10)
blur = cv2.GaussianBlur(img, (5, 5), 5)
# blur = cv2.GaussianBlur(img, (3, 3), 0)
# blur = img
# show_img(blur, 'blur')

# 灰度图
gray = cv2.cvtColor(blur,cv2.COLOR_BGR2GRAY)
# show_img(gray, 'gray')


# 提取边缘
edges = cv2.Canny(gray, 30, 60, apertureSize=3)
# show_img(edges, 'edges')

kernel = np.ones((7, 7), np.uint8)
img_dilate = cv2.dilate(edges, kernel)
# show_img(img_dilate, 'img_dilate')

# 寻找直线--霍夫变换


if 1:
    # 提取直线
    USE_HOUGH_P = 1
    COLOR = (255, 0, 0)

    img_black = np.zeros(img.shape, np.uint8)
    # img_black = img.copy()      # 绘制背景
    be_used_img = img_dilate.copy()     # 用来提取直线的图片
    # be_used_img = edges.copy()     # 用来提取直线的图片

    if USE_HOUGH_P:
        # lines = cv2.HoughLinesP(be_used_img, 3, 1.0 * np.pi / 180, threshold=200, minLineLength=200, maxLineGap=30)
        lines = cv2.HoughLinesP(be_used_img, 3, 1.0 * np.pi / 180, threshold=200, minLineLength=150,  maxLineGap=30)

        assert lines is not None, 'lines为空!'

        LINE_LEN = 2000
        for (x1, y1, x2, y2) in lines[:, 0]:
            print(x1, y1, ";", x2, y2)
            cv2.line(img_black, (x1, y1), (x2, y2), COLOR, 3)  # 画直线
    else:
        LINE_LEN = 2000
        lines = cv2.HoughLines(be_used_img, 3, np.pi / 180, 200)
        assert lines is not None, 'lines为空!'
        print('lines.shape:', lines.shape)
        for line in lines:
            for rho, theta in line:
                a = np.cos(theta)
                b = np.sin(theta)
                x0 = a * rho
                y0 = b * rho
                x1 = int(x0 + LINE_LEN * (-b))
                y1 = int(y0 + LINE_LEN * (a))
                x2 = int(x0 - LINE_LEN * (-b))
                y2 = int(y0 - LINE_LEN * (a))
                # 把直线显示在图片上
                cv2.line(img_black, (x1, y1), (x2, y2), COLOR, 2)
    print('--- lines.shape:', lines.shape)
    # show_img(img_black, 'USE_HOUGH_P')


# 求直线的斜率和截距
if 1:
    print(lines.shape)

    for (x1, y1, x2, y2) in lines[:, 0]:
        # print(x1, y1, ";", x2, y2)
        a = (x1, y1)
        b = (x2, y2)
        slope, intercept = np.polyfit(a, b, 1)
        print(slope)

    x = [4, 8]
    y = [5, 10]
    slope, intercept = np.polyfit(x, y, 1)
    print(slope)

    # from scipy.stats import linregress
    #
    # x = [4, 8]
    # y = [5, 10]
    # slope, intercept, r_value, p_value, std_err = linregress(x, y)
    # print(slope)

    # from sklearn import linear_model
    # import numpy as np
    #
    # reg = linear_model.LinearRegression()
    # # 假设数据是data
    # data = [1.71490784773981, 2.71490784773981, 3.71490784773981, 4.71490784773981]
    # # 对应序号是 range(len(data))
    # reg.fit(np.array(range(len(data))).reshape(-1, 1), np.array(data).reshape(-1, 1))
    #
    # # 斜率为
    # print(reg.coef_)
    # # 截距为
    # print(reg.intercept_)



# img_0 = img_black.copy()

# gray = cv2.cvtColor(img_black, cv2.COLOR_BGR2GRAY)
# show_img(gray, 'gray')
# ret, binary = cv2.threshold(gray, 20, 255, cv2.THRESH_BINARY)
# show_img(binary, 'binary')
# binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, anchor=(2, 0), iterations=5)
#
# binary = cv2.bitwise_not(img_black)

# import myutils
# b_gray = cv2.cvtColor(img_black, cv2.COLOR_BGR2GRAY)
# ret, binary = cv2.threshold(b_gray, 20, 255, cv2.THRESH_BINARY)

# digitCnts = cv2.findContours(b_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
# # 排序
# digitCnts = myutils.sort_contours(digitCnts, method="left-to-right")[0]

# show_img(binary, 'binary')
# show_img(digitCnts, 'digitCnts')



# # contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# print(len(contours), len(hierarchy))
#
# img_contour = img.copy()
# for c in contours:
#     peri = cv2.arcLength(c, True)
#     approx = cv2.approxPolyDP(c, 0.015 * peri, True)
#     print('len_app', approx)
#
#     if len(approx) == 4:
#         x, y, w, h = cv2.boundingRect(approx)
#         # (x, y), (w, h), theta = cv2.minAreaRect(approx)
#         print(approx)
#         cv2.rectangle(img_contour, (x, y), (x + w, y + h), (255, 0, 0), 2)
# show_img(img_contour, 'img_contour')


b_gray = cv2.cvtColor(img_black, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(b_gray, 20, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# img_black = np.zeros(img.shape, np.uint8)
img_contour = img.copy()
for contour in contours:
    (x, y, w, h) = cv2.boundingRect(contour)
    cv2.rectangle(img_contour, (x, y), (x + w, y + h), (255, 0, 0), 2)
show_img(img_contour, 'img_contour')

# contours.__len__()